# coding=utf8
# import copy
# from collections import Iterable
# from collections import Iterator

# Iterable 迭代对象
# (1) 可以通过__iter__()返回迭代器
# (2) Iterable通过for来实现迭代

# Iterator 迭代器
# (1) 通过 __next__() 返回下一个值
# (2) 通过 raise StopIteration代表迭代完成

# 判断是否为Iterable, [],{},'xxx',()均为迭代对象
# print(isinstance([], Iterable))
# print(isinstance({}, Iterable))
# print(isinstance('abc', Iterable))
# print(isinstance((x * x for x in range(5)), Iterable))
# print(isinstance(100, Iterable))

# 判断是否为Iterator
# print(isinstance([], Iterator))
# print(isinstance({}, Iterator))
# print(isinstance('abc', Iterator))
# print(isinstance(iter([]), Iterator))
# print(isinstance([].__iter__(), Iterator))
# print(isinstance(iter('abc'), Iterator))

# 简单Iterator演示, for循环作用于Iterator
# (1) 调用__init__,返回Iterator
# (2) 每循环一次调用 __next__,返回下一个值
# (3) 捕获StopIteration时停止循环
# (4) 实现了两个方法,所以既是Iterable,又是Iterator


# class IteratorTest(object):
#     def __init__(self, data):
#         self.data = data
#         self.index = len(data)
#
#     def __iter__(self):
#         return self
#
#     def __next__(self):
#         if self.index <= 0:
#             raise StopIteration
#         self.index -= 1
#         return self.data[self.index]


# IteratorTest既是Iterable,又是Iterator
# print(isinstance(it, Iterable))
# print(isinstance(it, Iterator))

# it = IteratorTest('ok')
# 第一次迭代有输出, 再次运行for不会有输出,已迭代完
# for item in it:
#     print(item)
# for item in it:
#     print(item)

# 除了使用for循环,也可以用next()迭代
# it = IteratorTest('ok')
# while True:
#     try:
#         print(next(it))
#     except StopIteration:
#         break

# 在迭代前通过deepcopy()可以复制一个迭代器
# it = IteratorTest('no')
# it_copy = copy.deepcopy(it)
# for item in it:
#     print(item)
# for item in it_copy:
#     print(item)

# 在迭代中途复制的迭代器,不是新的,也会从中途开始下一步迭代
# it = IteratorTest('ok')
# print(next(it))
# it_copy = copy.deepcopy(it)
# print(next(it))
# print(next(it_copy))


# class NoIterable(object):
#     def __init__(self, data):
#         self.data = data
#
#     def __getitem__(self, item):
#         print(item, end='')
#         return self.data[item]


# 只有__getitem__,既不是Iterable,又不是Iterator
# it = NoIterable('think')
# print(isinstance(it, Iterable))
# print(isinstance(it, Iterator))
# # 可以多次用for循环输出
# for item in it:
#     print(item, end='')
# for item in it:
#     print(item, end='')


# 实现斐波那契数列
class Fib(object):
    def __init__(self, limit):
        self.a, self.b = 0, 1
        self.limit = limit

    def __iter__(self):
        return self

    def __next__(self):
        self.a, self.b = self.b, self.a + self.b
        if self.a > self.limit:
            raise StopIteration
        return self.a


for n in Fib(1000):
    print(n, end=' ')
